#include "main.h"
#include "Bsp.h"

#include "fsm_evt.h"
#include "fsm_timer.h"

#include "string.h"

struct timer_list_t test_timer_node;

char test_buff[32] = {0};
uint8_t test_cnt = 0;

void test_timer_func(void)
{
    char tmp = 0;
    
    scanf("%c", &tmp);
    switch(tmp)
    {
        case 'r':
        case 'n':
            printf("Key Input is %s\n", test_buff);
        
            test_cnt = 0;
            memset(test_buff, 0, sizeof(test_buff));
        
            LL_GPIO_TogglePin(GPIOB, LL_GPIO_PIN_15);
            break;
        
        case 0:
            break;
        
        default:
            test_buff[test_cnt] = tmp;
            test_cnt ++;
        
            if (test_cnt >= 32) test_cnt = 0;
            break;
    }
}

// 主函数
int main(void) 
{
    // 硬件初始化
    BSP_init();
	
    // 系统任务
    fsm_system_evt_init();
    fsm_system_timer_init();

    // 用户任务
    fsm_timer_init(&test_timer_node, test_timer_func, 2, fsm_timer_one_flg);
    fsm_timer_start(&test_timer_node);

    // 打印复位来源
    if (LL_PWR_IsActiveFlag_SB())   // 待机标志
    {
        printf("Low Standby Startup\n");
    }
    else
    {
        printf("System Startup\n");
    }
    
    if (LL_PWR_IsActiveFlag_WU())   // 按键唤醒
    {
        printf("WU Startup\n");
    }
    
    if (LL_RCC_IsActiveFlag_PINRST())   // 按键复位
    {
        printf("RST Pin Startup\n");
    }
    
    if (LL_RCC_IsActiveFlag_SFTRST())   // 软件复位
    {
        printf("Soft Startup\n");
    }
    
    if (LL_RCC_IsActiveFlag_IWDGRST())   // 看门狗复位
    {
        printf("IWDG Startup\n");
    }
    
    // 运行任务
    BSP_Startup();
    
    return fsm_evt_tasks();
}

// 系统事件 处理函数
uint32_t fsm_system_evtfunc(fsm_msg_t *msg)
{
    uint8_t buf[4] = {0};
    
    if (fsm_msg_read(msg, buf) != 0)
    {
        switch (buf[0])
        {
        case 0x01:
            // 测试运行时间
//            BSP_DWT_Rst();
//            BSP_TickDelay(10);
//            printf("Runtime:%d us\n", BSP_DWT_Get_usTime());
            
            LL_GPIO_TogglePin(GPIOB, LL_GPIO_PIN_13);
            break;
        
        case 0x05:
            // fsm_timer_stop(&test_timer_node);
        default:
            break;
        }
    }

    return msg->msg_rx_cnt;
}

// 系统定时 处理函数
void fsm_system_timerfunc(void)
{
    uint8_t buf[4] = {1};
    
    // 发送信息
    fsm_evt_write(&system_evt_node, buf, 4);
    
    LL_GPIO_TogglePin(GPIOB, LL_GPIO_PIN_14);
}

/***************** SysTick中断设置 ********************/
void SysTick_Handler(void)
{
    fsm_timer_handler();
}

void fsm_cpu_sleep(void)
{
//    LL_RCC_ClocksTypeDef ClkCnt;
    
    // 睡眠模式
//    printf("Low Mode: Sleep In\n");
//    BSP_TickDelay(1);
    LL_LPM_EnableSleep();
    __WFI();
    
    
    // 停机模式
//    printf("Low Mode: Stop In\n");
//    BSP_TickDelay(2);
//    Bsp_SysTick_Stop();
//    LL_PWR_SetPowerMode(LL_PWR_MODE_STOP_LPREGU);
//    LL_LPM_EnableDeepSleep();
//    __WFI();
//    
//        // 停机模式 恢复时钟
//        LL_RCC_PLL_Enable();
//        while (LL_RCC_PLL_IsReady() != 1);
//        LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
//        Bsp_SysTick_Start();
    
    
    // 待机模式
//    printf("Low Mode: Standby In\n");
//    BSP_TickDelay(20);
//    
//        // 务必保证PA0 为低电平，否则高电平会导致异常唤醒死机, (PA0外置上拉电阻可以设置为输出模式低电平，否则不要设置输出模式)
//        LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_0, LL_GPIO_MODE_OUTPUT);
//        LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_0);
//
//    LL_PWR_EnableWakeUpPin(LL_PWR_WAKEUP_PIN1);
//    LL_PWR_ClearFlag_WU();
//    LL_PWR_SetPowerMode(LL_PWR_MODE_STANDBY);
//    LL_LPM_EnableSleepOnExit();
//    LL_LPM_EnableDeepSleep();
//    __WFI();
    
//    LL_RCC_GetSystemClocksFreq(&ClkCnt);
//    printf("Sleep Out, SysTickCLK:%d, HCLK:%d, PCLK1:%d, PCLK2:%d, SYSCLK:%d, SysSource:%x\n", SysTick->LOAD, ClkCnt.HCLK_Frequency, ClkCnt.PCLK1_Frequency, ClkCnt.PCLK2_Frequency, ClkCnt.SYSCLK_Frequency, LL_RCC_GetSysClkSource());
}

void fsm_system_idle(void)
{
    // 喂狗
    LL_IWDG_ReloadCounter(IWDG);
    
    // 低功耗
    fsm_cpu_sleep();
}
